package cn.migu.music.hangupsms.service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSON;

import cn.migu.music.common.exception.BusinessException;
import cn.migu.music.common.utils.LogUtils;
import cn.migu.music.hangupsms.cachemanage.LocalCacheManager;
import cn.migu.music.hangupsms.cachemanage.event.EventConstants;
import cn.migu.music.hangupsms.common.entity.*;
import cn.migu.music.hangupsms.repository.SmsSendFrequencySettingsMapper;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class SmsSendFrequencySettingsService implements SettingsApplyHandler {
    private static final String            TX_PREFIX = "smsFrequency";
    private static final String            OP_TABLE  = "t_migu_hangup_sms_send_frequency";
    @Autowired
    private SmsSendFrequencySettingsMapper smsSendFrequencySettingsMapper;
    @Autowired
    private SettingsChangeLogService       changeLogService;
    @Autowired
    private LocalCacheManager              cacheManager;

    @PostConstruct
    public void init() {
        changeLogService.registerApply(TX_PREFIX, this);
    }

    /**
     * 新增发送次数限制配置
     * 
     * @param smsFrequencyOperation
     * @return
     */
    @Transactional
    @PostMapping("/hangupsms/settings/sms-frequency/add/v1.0")
    public SettingResponse<String> addSmsSendFrequencySettings(@RequestBody SmsFrequencyOperation smsFrequencyOperation) {
        SettingResponse<String> response = new SettingResponse<>();
        if (isParamInvalidate(response, smsFrequencyOperation)) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            return response;
        }
        SmsSendFrequencySettings settings = new SmsSendFrequencySettings();
        settings.setProvinceId(smsFrequencyOperation.getProvinceId());
        settings.setDayFrequency(smsFrequencyOperation.getDayFrequency());
        settings.setWeekFrequency(smsFrequencyOperation.getWeekFrequency());
        settings.setMonthFrequency(smsFrequencyOperation.getMonthFrequency());
        settings.setApplyStatus(0);
        try {
            saveToDb(smsFrequencyOperation, settings);
        } catch (Exception e) {
            LogUtils.error(e, log, "save db error");
            response.setResultCode(SettingResponse.ERROR_CODE);
            response.setResultMessage(e.getMessage());
            return response;
        }
        response.setResultCode(SettingResponse.SUCCESS_CODE);
        response.setResultMessage(SettingResponse.SUCCESS_MSG);
        String txId = TX_PREFIX + "." + settings.getProvinceId();
        response.setData(txId);
        return response;
    }

    @Transactional
    public void saveToDb(SmsFrequencyOperation smsFrequencyOperation, SmsSendFrequencySettings settings) {
        SmsSendFrequencySettings dbRecord = smsSendFrequencySettingsMapper.getIgnoreDelete(smsFrequencyOperation.getProvinceId());
        if (dbRecord == null) {
            smsSendFrequencySettingsMapper.add(settings);
        } else if (dbRecord.getDeleteFlag() == 1) {
            settings.setDeleteFlag(0);
            smsSendFrequencySettingsMapper.updateFrequency(settings);
        } else {
            throw BusinessException.newInstance("data exists!");
        }
        smsFrequencyOperation.setOperationEnum(SettingOperationEnum.ADD);
        changeLogService.addLog(smsFrequencyOperation, OP_TABLE, settings.getProvinceId(), JSON.toJSONString(settings), "");
    }

    private boolean isParamInvalidate(SettingResponse<String> response, SmsFrequencyOperation smsFrequencyOperation) {
        response.setResultCode(SettingResponse.ERROR_CODE);
        if (StringUtils.isEmpty(smsFrequencyOperation.getProvinceId())) {
            response.setResultMessage("province id is empty");
            return true;
        }
        if (smsFrequencyOperation.getMonthFrequency() == null ||
            smsFrequencyOperation.getWeekFrequency() == null ||
            smsFrequencyOperation.getDayFrequency() == null) {
            response.setResultMessage("some frequency is null");
            return true;
        }
        response.setResultCode(SettingResponse.SUCCESS_CODE);
        return false;
    }

    /**
     * 修改发送次数限制配置
     * 
     * @param smsFrequencyOperation
     * @return
     */
    @Transactional
    @PostMapping("/hangupsms/settings/sms-frequency/edit/v1.0")
    public SettingResponse<String> updateSmsSendFrequencySettings(@RequestBody SmsFrequencyOperation smsFrequencyOperation) {
        SettingResponse<String> response = new SettingResponse<>();
        if (isParamInvalidate(response, smsFrequencyOperation)) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            return response;
        }
        SmsSendFrequencySettings settingsOld = smsSendFrequencySettingsMapper.get(smsFrequencyOperation.getProvinceId());
        if (settingsOld == null) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            response.setResultMessage("no settings for province:" + smsFrequencyOperation.getProvinceId());
            return response;
        }
        SmsSendFrequencySettings settings = new SmsSendFrequencySettings();
        settings.setProvinceId(smsFrequencyOperation.getProvinceId());
        settings.setDayFrequency(smsFrequencyOperation.getDayFrequency());
        settings.setWeekFrequency(smsFrequencyOperation.getWeekFrequency());
        settings.setMonthFrequency(smsFrequencyOperation.getMonthFrequency());
        settings.setChangeTime(LocalDateTime.now());
        settings.setApplyStatus(0);
        smsSendFrequencySettingsMapper.updateFrequency(settings);
        smsFrequencyOperation.setOperationEnum(SettingOperationEnum.EDIT);
        changeLogService.addLog(smsFrequencyOperation, OP_TABLE, settings.getProvinceId(), JSON.toJSONString(settings),
            JSON.toJSONString(settingsOld));
        response.setResultCode(SettingResponse.SUCCESS_CODE);
        response.setResultMessage(SettingResponse.SUCCESS_MSG);
        String txId = TX_PREFIX + "." + settings.getProvinceId();
        response.setData(txId);
        return response;
    }

    /**
     * 查询发送次数限制配置
     * 
     * @param provinceId
     *            省编码
     * @return
     */
    @GetMapping("/hangupsms/settings/sms-frequency/display/v1.0")
    public SettingResponse<List<SmsSendFrequencySettings>> getSmsSendFrequency(@RequestParam String provinceId) {
        SettingResponse<List<SmsSendFrequencySettings>> response = new SettingResponse<>();
        if (StringUtils.isEmpty(provinceId)) {
            List<SmsSendFrequencySettings> settingsList = smsSendFrequencySettingsMapper.getAllSettings();
            response.setData(settingsList);
        } else {
            List<SmsSendFrequencySettings> settingsList = new ArrayList<>(1);
            SmsSendFrequencySettings settings = smsSendFrequencySettingsMapper.get(provinceId);
            if (settings != null) {
                settingsList.add(settings);
            }
            response.setData(settingsList);
        }
        response.setResultCode(SettingResponse.SUCCESS_CODE);
        return response;
    }

    /**
     * 删除发送次数限制配置
     * 
     * @param smsFrequencyOperation
     * @return
     */
    @Transactional
    @PostMapping("/hangupsms/settings/sms-frequency/delete/v1.0")
    public SettingResponse<String> deleteSmsSendFrequencySettings(@RequestBody SmsFrequencyOperation smsFrequencyOperation) {
        SettingResponse<String> response = new SettingResponse<>();
        String provinceId = smsFrequencyOperation.getProvinceId();
        if (StringUtils.isEmpty(provinceId) || StringUtils.equals("default", provinceId)) {
            response.setResultMessage("invalid province id");
            response.setResultCode(SettingResponse.ERROR_CODE);
            return response;
        } else {
            SmsSendFrequencySettings settings = smsSendFrequencySettingsMapper.get(provinceId);
            if (settings == null) {
                response.setResultCode(SettingResponse.ERROR_CODE);
                response.setResultMessage("data not exist!");
            } else {
                smsSendFrequencySettingsMapper.delete(provinceId);
                SmsSendFrequencySettings settingsDeleted = smsSendFrequencySettingsMapper.getIgnoreDelete(provinceId);
                smsFrequencyOperation.setOperationEnum(SettingOperationEnum.DELETE);
                changeLogService.addLog(smsFrequencyOperation, OP_TABLE, provinceId, JSON.toJSONString(settings), JSON.toJSONString(settingsDeleted));
                response.setResultCode(SettingResponse.SUCCESS_CODE);
                response.setResultMessage(SettingResponse.SUCCESS_MSG);
                response.setData(TX_PREFIX + "." + provinceId);
            }
        }
        return response;
    }

    @Override
    public boolean apply(String rowId, String user) {
        SmsSendFrequencySettings settings = smsSendFrequencySettingsMapper.getIgnoreDelete(rowId);
        if (settings != null) {
            smsSendFrequencySettingsMapper.updateApplyStatus(rowId, 1, LocalDateTime.now());
            SmsSendFrequencySettings updatedSettings = smsSendFrequencySettingsMapper.getIgnoreDelete(rowId);
            if (updatedSettings.getApplyStatus() != 1) {
                return false;
            }
            cacheManager.broadcastEvent(EventConstants.SMS_SEND_FREQUENCY_CHANGED_EVENT);
            OperateBase operateBase = new OperateBase();
            operateBase.setOperationEnum(SettingOperationEnum.APPLY);
            operateBase.setOperateUser(user);
            changeLogService.addLog(operateBase, OP_TABLE, settings.getProvinceId(), JSON.toJSONString(updatedSettings), JSON.toJSONString(settings));
            return true;
        }
        return false;
    }
}
